package visualTwo;

import globalCode.TableHandler;
import globalCode.UserData;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;

public class UserNode implements Comparable<UserNode>{
	int id;
	double r, theta;
	Color c;
	int rad;
	private UserData uData;
	
	public UserNode(){
		this(0, 0, 0, Color.BLACK, 0, null);
	}
	
	public UserNode(int i, int mag, int angle, Color col, int s, TableHandler th){
		id = i;
		r = mag;
		theta = angle;
		c = col;
		rad = s;
		uData = new UserData(i, th);
	}
	
	public UserNode(int i, int xC, int yC, int s, TableHandler th){
		this(i, xC, yC, Color.BLACK, s, th);
		int r = (int) (Math.random()*100+1);
		int g = (int) (Math.random()*100+1);
		int b = (int) (Math.random()*100+1);
		Color ran = new Color(155+r, 155+g, 155+b);
		c=ran;
	}
	
	public void draw(Graphics g, double cirRad, double thetaMod){
		g.setColor(c);
		double x = getAdjX(cirRad, thetaMod);
		double y = getAdjY(cirRad, thetaMod);
		g.fillOval((int)x-rad, (int)y-rad, rad*2, rad*2);
		//System.out.println("rad: "+rad);
		Font font = new Font("Dialog", Font.PLAIN, (int)(12*rad/17.0));
		g.setFont(font);
		g.setColor(Color.BLACK);
		g.drawString(""+id, (int)x-rad+rad/6, (int)y+rad/6);
	}
	
	public void drawLockedBorder(Graphics2D g, double cirRad, double thetaMod){
		g.setColor(Color.WHITE);
		g.setStroke(new BasicStroke((float) (rad/7)));
		double x = getAdjX(cirRad, thetaMod)-17*rad/16;
		double y = getAdjY(cirRad, thetaMod)-17*rad/16;
		g.drawOval((int)x, (int)y, (int)(rad*17/8), (int)(rad*17/8));
	}
	
	public void drawInfo(Graphics2D g, double cirRad, double thetaMod){
		g.setColor(Color.WHITE);
		double cirX = getAdjX(cirRad, thetaMod);
		double cirY = getAdjY(cirRad, thetaMod);
		double yDir = Math.sin(thetaMod+theta+Math.PI);
		double xDir = Math.cos(thetaMod+theta+Math.PI);
		double yDir1 = Math.sin(thetaMod+theta+Math.PI+Math.PI/4);
		double xDir1 = Math.cos(thetaMod+theta+Math.PI+Math.PI/4);
		double yDir2 = Math.sin(thetaMod+theta+Math.PI-Math.PI/4);
		double xDir2 = Math.cos(thetaMod+theta+Math.PI-Math.PI/4);
		if(r==0){
			System.out.println("ADFADSFADS R=0 OMG LOL WTF");
			yDir = Math.sin(Math.PI/4);
			xDir = Math.cos(Math.PI/4);
			xDir1 = Math.cos(Math.PI/2);
			yDir1 = Math.sin(Math.PI/2);
			xDir2 = Math.cos(0);
			yDir2 = Math.sin(0);
		}
		double xC = cirX + xDir*rad*11;
		double yC = cirY + yDir*rad*9;
		double xC1 = xC + xDir1*rad*4;
		double yC1 = yC + yDir1*rad*4;
		double xC2 = xC + xDir2*rad*4;
		double yC2 = yC + yDir2*rad*4;
		
		
		g.setColor(c);
		g.setStroke(new BasicStroke((float) (cirRad*2/2000+1)));
		g.drawLine((int)cirX, (int)cirY, (int)xC1, (int)yC1);
		g.drawLine((int)cirX, (int)cirY, (int)xC2, (int)yC2);
		g.drawRoundRect((int)xC-rad*7, (int)yC-rad*5, rad*14, rad*10, rad/2, rad/2);
		g.setColor(Color.WHITE);
		g.fillPolygon(new int[]{(int)cirX, (int)xC1, (int)xC2}, new int[]{(int)cirY, (int)yC1, (int)yC2}, 3);
		g.fillRoundRect((int)xC-rad*7, (int)yC-rad*5, rad*14, rad*10, rad/2, rad/2);
		
		
		
		Font font = new Font("Dialog", Font.PLAIN, (int)(12*rad/17.0));
		g.setFont(font);
		g.setColor(Color.BLACK);
		String[] uDataString = uData.toString().split("\n");
		for(int i = 0; i<uDataString.length; i++)
			g.drawString(uDataString[i], (int)xC-(int)6*rad, (int)yC-rad*4+i*(int)(12*rad/17.0+2));
	}

	@Override
	public int compareTo(UserNode other) {
		return this.id-other.id;
	}
	
	public boolean contains(int xT, int yT, double cirRad, double thetaMod){
		double x = getAdjX(cirRad, thetaMod);
		double y = getAdjY(cirRad, thetaMod);
		return((x-xT)*(x-xT)+(y-yT)*(y-yT)<rad*rad);
	}

	public int getConnectivity(int group) {
		return uData.getGroupConnectivity(group);
	}

	public void setConnectivity(int group, int connectivity) {
		uData.setConnectivity(group, connectivity);
	}
	
	public boolean seperate(UserNode other, double cirRad){
		double x = getAdjX(0.5, 0);
		double y = getAdjY(0.5, 0);
		double xT = other.getAdjX(0.5, 0);
		double yT = other.getAdjY(0.5, 0);
		double distance = Math.sqrt((x-xT)*(x-xT)+(y-yT)*(y-yT));
		
		//System.out.println("xT="+xT+"  yT="+yT+"  x="+x+"  y="+y);
		//System.out.println("dist+" +distance+" raddiff "+(this.rad+other.rad));
		if(Double.isNaN(xT) || Double.isNaN(yT) || Double.isNaN(x) || Double.isNaN(y))
			System.exit(1);
		if(distance>this.rad/cirRad+other.rad/cirRad){
			return false;
		}
		else{
			double xDiff = xT-x;
			double yDiff = yT-y;
			double angle = 0;
			if(xDiff != 0 && yDiff != 0)
				angle=Math.atan2(yDiff, xDiff);
			else if(yDiff!=0)
				angle = 90;
			else if(xDiff!=0)
				angle=0;
			else{
				xDiff=1;
				angle=90;
			}
				
			double changeMag = (this.rad/cirRad+other.rad/cirRad)-distance+1/cirRad;
			//System.out.println("CM "+changeMag);
			double xChange = (changeMag*Math.cos(angle))*xDiff/Math.abs(xDiff);
			System.out.println("xC: "+xChange);
			double yChange = (changeMag*Math.sin(angle))*yDiff/Math.abs(yDiff);
			System.out.println("yCc: "+yChange);
			//System.out.println(yChange);
			if(yDiff==0)
				yChange = 0;
			if(xDiff==0)
				xChange = 0;
			if(xDiff != 0 || yDiff != 0){
				System.out.println(this.getX()+", "+this.getY()+", "+this.r);
				this.resolvePolar(x-xChange, y-yChange, 0.5);
				System.out.println(this.getX()+", "+this.getY()+", "+this.r);
				other.resolvePolar(xT+xChange, yT+yChange, 0.5);
			}			
			
			return true;
		}
	}
	
	void resolvePolar(double x, double y, double cirRad) {
		theta = Math.atan2(-1*y+cirRad,x-cirRad);
		if(Double.isNaN(theta))
			System.out.println(x+" "+y+" "+cirRad);
		r = (x-cirRad)/(Math.cos(theta)*cirRad);
		
	}

	public double getX(){
		return r*Math.cos(theta);
	}
	
	public double getY(){
		return r*Math.sin(theta);
	}
	
	public double getAdjX(double cirRad, double thetaMod){
		return r*Math.cos(theta+thetaMod)*cirRad+cirRad;
	}
	
	public double getAdjY(double cirRad, double thetaMod){
		return r*Math.sin(theta+thetaMod)*cirRad+cirRad;
	}
}
